#include <iostream>
#include "HEALPIX_Data.h"
#include "fitsio.h"

using namespace std;

int HEALPIX_Data::Get_Val(float in1, float in2, void *out) {

	cout << "HEALPIX_Data::Get_Val Entering the Get_Val method in the derived calss HEALPIX_Data" << endl;
	return EXIT_SUCCESS;

}
int HEALPIX_Data::load() {

	cout << "HEALPIX_Data::load Entering the load method in the derived calss HEALPIX_Data" << endl;
	return EXIT_SUCCESS;
}


HEALPIX_Data::HEALPIX_Data (char *filename) {

	/*! Now this has to load everything in -
	We know the format a FITS BINARY TABLE - so we need to use some fitsio calls
	to get at the data. This comes from the RTS routine load_mwahpx_from_file

	*/

	float nullval=0;;
	int anynul=0;
	fitsfile *fptr=NULL;
	int status=0,nfound=0,hdutype=0;
	long nside=0,naxis=0;
	long *naxes=NULL;
	long nrow=0,nrows=0,pcount=0;
	int tfields=0;
   	char extname[64];
	
	cout << "HEALPIX_Data::HEALPIX_Data(char *filename) Overloaded Constructor" << endl;
	nullval = HEALPIX_NULLVAL;

	try {
 
		if (fits_open_file(&fptr,filename,0,&status)) {
			throw("fits_open_file has failed\n");
		}

		/* currently the binary table is in the next hdu */
   
		if (fits_movrel_hdu(fptr,1,&hdutype,&status)) throw("Cannot move to next HDU\n");
   
		if (fits_get_hdu_type(fptr, &hdutype, &status)) throw("Cannot get HDUTYPE\n");
   
		if (!(hdutype == BINARY_TBL)) {
			throw("ERROR: file does not contain MWAHPX data. Or wrong HDU tested. Current version of MWAHPX expects BINARY TABLE in the second HDU\n");
		}
		else {
    
			if (fits_read_key_lng(fptr, "NAXIS", &naxis, 0x0, &status)) {
				throw("fits_read_key has failed on NAXIS\n");
			}
    
			naxes = (long *) malloc(naxis*sizeof(long));

			if (fits_read_keys_lng(fptr, "NAXIS", 1, (int)naxis, naxes, &nfound,&status)) {
				throw("fits_read_key has failed on NAXIS\n");
			}

			if (nfound > 1)
				nrow = naxes[1];

			if (!nrow) {
				throw("ERROR: Could not determine image size\n");
			}

			/* Number of pixels per side of each base-resolution pixel. */

			if (fits_read_key_lng(fptr, "NSIDE", &nside, 0x0, &status)) {
				throw("NSIDE not found\n");
			}
			cout << "I think NSIDE is " << nside << endl;

			if (fits_read_btblhdr(fptr, 32, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount, &status)) {
   				throw("Cannot read binary table\n"); 
			}
			fprintf(stdout,"EXTENSION %s\n",extname);
			if (strncmp(extname, "WEIGHTED", 8) == 0) {
				fprintf(stdout,"STATUS: Weighted!\n");
				throw("Cannot yet read a weighted file\n");

			}

			/*! Need to allocate some space for the HEALPIX Data */

			data = new healpix_t[nrow];


			for (int irow=0; irow < nrow ; irow++) {
				cout << "Reading Row: " << irow << "\r" ;

				if (fits_read_col(fptr, TINT, 1, irow+1, 1,1,
							&nullval, &data[irow].pixel, &anynul, &status)) {
					throw("Failed column read\n");
				}

				if (fits_read_col(fptr,TFLOAT,2,irow+1,1,1,
							&nullval, &data[irow].value[0], &anynul, &status)) {
					throw("Failed column read\n");
				}

				if (fits_read_col(fptr,TFLOAT,3,irow+1,1,1,
							&nullval, &data[irow].value[1], &anynul, &status)) {
					throw("Failed column read\n");
				}


				if (fits_read_col(fptr,TFLOAT,4,irow+1,1,1,
							&nullval, &data[irow].value[2], &anynul, &status)) {
					throw("Failed column read\n");
				}

				if (fits_read_col(fptr,TFLOAT,5,irow+1,1,1,
							&nullval, &data[irow].value[3], &anynul, &status)) {
					throw("Failed column read\n");
				}

				if (fits_read_col(fptr,TFLOAT,6,irow+1,1,1,
							&nullval, &data[irow].weight[0], &anynul, &status)) {
					throw("Failed column read\n");
				}
			
	
			}

			cout << "\nRead " << nrow << " rows in total" << endl;
			ndata=nrows;
		}
	}
	catch(char const *e) {
		fits_report_error(stderr,status);
		cerr << e << endl;
	}

}	
HEALPIX_Data::HEALPIX_Data () {

	cout << "HEALPIX_Data::HEALPIX_Data() Default Constructor" << endl;
	data = NULL;
}
HEALPIX_Data::~HEALPIX_Data () {

	cout << "HEALPIX_Data::~HEALPIX_Data() Default Destructor" << endl;
	if (data != NULL) {
		delete[] data;
	}
}
	
